<?php

namespace App\Services\Scenic;

use App\Jobs\Scenic\SyncTuNiuScenicDetail;
use App\Services\Http;
use Illuminate\Support\Facades\Cache;

class TuNiuScenicService
{
    const SCENIC_LIST_URI = '/Ticket/scenicList';
    const SCENIC_DETAIL_URI = '/Ticket/scenicDetail';
    const SCENIC_TICKET_DETAIL_URI = '/Ticket/detail';

    protected string $apiUrl;
    protected string $apikey;
    protected string $secretkey;

    public function __construct()
    {
        $this->apiUrl = config('trip.scenic.tuniu.apiurl');
        $this->secretkey = config("trip.scenic.tuniu.secretkey");;
        $this->apikey = config("trip.scenic.tuniu.apikey");;
    }

    /**
     * 设置签名
     * @param $params
     * @return string
     */
    public function makeSign($params): string
    {
        $tmpArr = [];
        $tmpArr[] = $this->secretkey;
        ksort($params);
        foreach ($params as $key => $value) {
            if ($key == 'sign' || empty($value)) {
                continue;
            }
            if (is_array($value) || is_object($value)) {
                $value = json_encode($value);
            }
            $tmpArr[] = sprintf('%s=%s', $key, $value);
        }
        $tmpArr[] = $this->secretkey;
        $str = implode('&', $tmpArr);

        return strtoupper(md5($str));
    }

    /**
     * 组合参数
     * @param $params
     * @return array
     */
    public function buildParams($params): array
    {
        $newParams = [
            'apiKey' => $this->apikey,
            'timestamp' => date('Y-m-d H:i:s')
        ];
        $signStr = $this->makeSign(array_merge($newParams,$params));
        $newParams['sign'] = $signStr;
        $newParams['data'] = $params;

        return $newParams;
    }

    /**
     * 查询景点
     * @param string $keyword
     * @param int $page
     * @param int $pageSize
     * @return mixed
     * @throws \Exception
     */
    public function searchScenic(string $keyword,int $page,int $pageSize)
    {
        $cacheKey = "scenicService:tuNiu:searchScenic:".md5($keyword.$page.$pageSize);
        $res = Cache::get($cacheKey);
        if (!empty($res)) {
            $result = json_decode($res);
            return $result->data;
        }
        $data = [
            'pageSize'=>$pageSize,
            'page'=>$page,
            'key'=>$keyword
        ];
        $params = $this->buildParams($data);
        $httpService = new Http();
        $httpService->setUrl($this->apiUrl.self::SCENIC_LIST_URI);
        $httpService->setParam($params,true,true);
        $res = $httpService->postJson();
        $result = json_decode($res);
        if (!$result->success){
           throw new \Exception($result->msg,$result->errorCode);
        }
        $cacheTime = config('trip.ttl.day') * 1;
        Cache::put($cacheKey, $res, $cacheTime);
        if (!empty($result->data->rows)){
            foreach ($result->data->rows as $row){
                SyncTuNiuScenicDetail::dispatch($row->scenicId)->onQueue('{syncTuNiuScenic}');
            }
        }
        return $result->data;
    }

    /**
     * 获取景点详情
     * @param string $scenicId
     * @return mixed
     * @throws \Exception
     */
    public function scenicDetail(string $scenicId)
    {
        $cacheKey = "scenicService:tuNiu:scenicDetail:".$scenicId;
        $res = Cache::get($cacheKey);
        if (!empty($res)) {
            $result = json_decode($res);
            return $result->data;
        }
        $data = [
            'scenicId'=>$scenicId,
        ];
        $params = $this->buildParams($data);
        $httpService = new Http();
        $httpService->setUrl($this->apiUrl.self::SCENIC_DETAIL_URI);
        $httpService->setParam($params,true,true);
        $res = $httpService->postJson();
        $result = json_decode($res);
        if (!$result->success){
            throw new \Exception($result->msg,$result->errorCode);
        }
        $cacheTime = config('trip.ttl.day') * 1;
        Cache::put($cacheKey, $res, $cacheTime);
        return $result->data;
    }

    /**
     * 获取门票详情
     * @param string $productId
     * @return mixed
     * @throws \Exception
     */
    public function ticketDetail(string $productId)
    {
        $cacheKey = "scenicService:tuNiu:ticketDetail:".$productId;
        $res = Cache::get($cacheKey);
        if (!empty($res)) {
            $result = json_decode($res);
            return $result->data;
        }
        $data = [
            'productId'=>$productId,
        ];
        $params = $this->buildParams($data);
        $httpService = new Http();
        $httpService->setUrl($this->apiUrl.self::SCENIC_TICKET_DETAIL_URI);
        $httpService->setParam($params,true,true);
        $res = $httpService->postJson();
        $result = json_decode($res);
        if (!$result->success){
            throw new \Exception($result->msg,$result->errorCode);
        }
        $cacheTime = config('trip.ttl.day') * 1;
        Cache::put($cacheKey, $res, $cacheTime);
        return $result->data;
    }

}
